package ex55.mm.flow.impound.quote;

import ex55.mm.flow.impound.quote.common.rdsdb.RdsDBHelper;
import ex55.mm.flow.impound.quote.common.redis.push.Receiver;
import ex55.mm.flow.impound.quote.exchange.api.SubscriptionOptions;
import ex55.mm.flow.impound.quote.exchange.api.WebSocketWatchDog;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

@SpringBootApplication(exclude = {JooqAutoConfiguration.class, DataSourceAutoConfiguration.class})
public class MMImpoundQuoteApplication {

	public static void main(String[] args) {
		ApplicationContext ctx = SpringApplication.run(MMImpoundQuoteApplication.class, args);

//		StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
//		Receiver receiver = ctx.getBean(Receiver.class);
//
//		while (receiver.getCount() == 0) {
//			template.convertAndSend("chat", "Hello from Redis!");
//			try {
//				Thread.sleep(500L);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//		}
	}

	@Bean(destroyMethod = "close")
	public RdsDBHelper rdsDBHelper(
			@Value("${db.mysql}")
					String mysql
	) {
		return RdsDBHelper.createRdsHelperMysqlUrl(mysql);
	}

	@Bean(initMethod = "start")
	public AggregateDataCalculator quote_1(RdsDBHelper rdsDBHelper, AggregateDataFacade aggregateDataFacade) {
		return new AggregateDataCalculator(rdsDBHelper, aggregateDataFacade);
	}

	@Bean
	public AggregateDataFacade aggregateDataFacade(
			RdsDBHelper rdsDBHelper,
			WebSocketWatchDog webSocketWatchDog) {
		return new AggregateDataFacade(rdsDBHelper, webSocketWatchDog);
	}

	@Bean
	public WebSocketWatchDog webSocketWatchDog() {
		return new WebSocketWatchDog(
				new SubscriptionOptions(
						"ws://3.113.193.72:8090/xchange/marketdata",
						true,
						60_000L));
	}

	@Bean
	public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
											MessageListenerAdapter listenerAdapter) {
		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.setConnectionFactory(connectionFactory);
		container.addMessageListener(listenerAdapter, new PatternTopic("/xchange/marketdata/orderbookcache"));

		return container;
	}

	@Bean
	public MessageListenerAdapter listenerAdapter(Receiver receiver) {
		return new MessageListenerAdapter(receiver, "receiveMessage");
	}

	@Bean
	public Receiver receiver(AggregateDataFacade aggregateDataFacade) {
		return new Receiver(aggregateDataFacade);
	}

	@Bean
	public StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
		return new StringRedisTemplate(connectionFactory);
	}

}
